package com.weir.member.oauth;

import com.fasterxml.jackson.annotation.JsonProperty;

import io.vertx.codegen.annotations.Nullable;
import io.vertx.core.http.HttpServerRequest;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.http.HttpRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.client.Entity;
import jakarta.ws.rs.client.WebTarget;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.NewCookie;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;
import jakarta.ws.rs.core.SecurityContext;
import jakarta.ws.rs.core.UriBuilder;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;

/**
 * Shows how to create a simple OAuth integration.
 *
 * To Use:
 *
 * export CLIENT_ID=XXX
 * export CLIENT_SECRET=XXX
 * mvn compile quarkus:dev
 *
 *
 * in browser navigate to http://2a38-223-91-168-157.ngrok.io/oauth/login
 */
@Path("/oauth")
public class GiteeOauthResource {

    public static class GithubAuthReq {

        @JsonProperty("client_id")
        public final String clientId;

        @JsonProperty("client_secret")
        public final String clientSecret;

        @JsonProperty("redirect_url")
        public final String redirectUrl = "http://2a38-223-91-168-157.ngrok.io/oauth/gitee/callback";

        @JsonProperty("scope")
        public final String scope = "read:user read:org";

        @JsonProperty("state")
        public final String state = UUID.randomUUID().toString();

        @JsonProperty("allow_signup")
        public final String allowSignup = "false";

        public GithubAuthReq(String clientId, String clientSecret) {
            this.clientId = clientId;
            this.clientSecret = clientSecret;
        }

        public String getAuthorizeUri() {
        	String u ="https://gitee.com/oauth/authorize?client_id=%s&redirect_uri=%s&response_type=code&state=%s";
        	return String.format(u, clientId,redirectUrl,state);
//            return UriBuilder.fromUri("https://gitee.com/oauth/authorize")
//                    .queryParam("client_id", clientId)
//                    .queryParam("redirect_url", redirectUrl)
//                    .queryParam("response_type", "code")
////                    .queryParam("scope", scope)
////                    .queryParam("state", state)
////                    .queryParam("allow_signup", allowSignup)
//                    .build();
        }

        public String getCodeUri(String code) {
        	String u ="https://gitee.com/oauth/token?grant_type=authorization_code&client_id=%s&redirect_uri=%s&state=%s&client_secret=%s&code=";
        	return String.format(u, clientId,redirectUrl,state,clientSecret,code);
//            return UriBuilder.fromUri("https://gitee.com/oauth/token")
//                    .queryParam("grant_type", "authorization_code")
//                    .queryParam("client_id", clientId)
//                    .queryParam("client_secret", clientSecret)
//                    .queryParam("redirect_url", redirectUrl)
//                    .queryParam("code", code)
//                    .queryParam("state", state)
//                    .build();
        }

    }

    private Client client = ResteasyClientBuilder.newClient();
    private Map<String, GithubAuthReq> outstandingRequests = new HashMap<>();
    private Map<String, String> accessTokens = new HashMap<>();

//    @Context HttpServletRequest request;
/**
 * Unable to find contextual data of type: jakarta.servlet.http.HttpServletRequest
 * 报错  无法注入 @Context HttpServletRequest request  不知什么原因
 * @param request
 * @return
 */
    @Path("/home")
    @Produces(MediaType.APPLICATION_JSON)
    @GET
    public Response home(@Context HttpServletRequest request) {
        Cookie sessionCookie = null;
        for (Cookie cookie : request.getCookies()) {
            if (cookie.getName().equals("session")) {
                sessionCookie = cookie;
            }
        }
        if (sessionCookie == null) {
            return Response.seeOther(UriBuilder.fromPath("/oauth/login").build()).build();
        }
        
        String token = accessTokens.get(sessionCookie.getValue());
        final String bearer = "token " + token;
        final String teamsJson = client.target("https://gitee.com/api/v5/user").request().header("Authorization", bearer).get().readEntity(String.class);
        final String orgsJson = "";
        return Response.ok()
                .entity("{\"teams\":" + teamsJson + ",\"orgs\":" + orgsJson + "}")
                .build();
    	
    }
    
    /**
     * 获取用户信息
     * get
     */
//    public static JSONObject getUserInfo(String url) throws IOException {
//        JSONObject jsonObject = null;
//        CloseableHttpClient client = HttpClients.createDefault();
//
//        HttpGet httpGet = new HttpGet(url);
//        httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36");
//        HttpResponse response = client.execute(httpGet);
//        HttpEntity entity = response.getEntity();
//
//        if (entity != null) {
//            String result = EntityUtils.toString(entity, "UTF-8");
//            jsonObject = JSONObject.parseObject(result);
//        }
//
//        httpGet.releaseConnection();
//
//        return jsonObject;
//    }

    @GET
    @Path("/gitee/callback")
    public Response callback(@QueryParam("state") String state, @QueryParam("code") String code) throws IOException {
    	
        GithubAuthReq req = outstandingRequests.remove(state);
        if (req == null || !req.state.equals(state)) {
        	return Response.status(Status.BAD_REQUEST).entity("not accepted").build();
        }

        WebTarget target = this.client.target("https://gitee.com/oauth/token");
        Response response = target.request()
        		.post(
        		Entity.json(new GiteeVo("e697e2db0de6099465fa9fccd7e98446984a32fa43827e7db671d279bc0c8c1a",
        				"c8912c4e06474b6b95eaa1374e7ba71ae6401c375b2135e9eb1cb26eb49bf632",
        				"http://2a38-223-91-168-157.ngrok.io/oauth/gitee/callback",code)));
        if (response.getStatus() != 200) {
            return Response.status(Status.BAD_REQUEST).entity("not accepted by github").build();
        }
        
        Map readEntity = response.readEntity(Map.class);
        
//        System.out.println("readEntity----------->" + readEntity);
        
        final String sessionId = UUID.randomUUID().toString();
        accessTokens.put(sessionId, readEntity.get("access_token").toString());
        return Response.seeOther(UriBuilder.fromPath("/oauth/home").build())
                .cookie(new NewCookie("session", sessionId))
                .build();
    }
    
    /**
     * 获取Access Token
     * post
     */
//    public static JSONObject getAccessToken(String url) throws IOException {
//        HttpClient client = HttpClients.createDefault();
//        HttpPost httpPost = new HttpPost(url);
//        httpPost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36");
//        HttpResponse response = client.execute(httpPost);
//        HttpEntity entity = response.getEntity();
//        if (null != entity) {
//            String result = EntityUtils.toString(entity, "UTF-8");
//            return JSONObject.parseObject(result);
//        }
//        httpPost.releaseConnection();
//        return null;
//    }

    @GET
    @Path("/login")
    @Produces(MediaType.TEXT_HTML)
    public Response login() {
    	String getenv = "e697e2db0de6099465fa9fccd7e98446984a32fa43827e7db671d279bc0c8c1a";
    	String getenv2 = "c8912c4e06474b6b95eaa1374e7ba71ae6401c375b2135e9eb1cb26eb49bf632";
        GithubAuthReq req = new GithubAuthReq(getenv, getenv2);
        outstandingRequests.put(req.state, req);
        String authorizeUri = req.getAuthorizeUri();
        URL url = null;
		try {
			url = new URL(authorizeUri);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
        return Response
                .ok(String.format("<body><a href='%s'>click to login with gitee</a></body>", url))
                .build();
    }
    
    @GET
    public String name() {
		return "hello";
	}
}